#ifndef DOUBLE_DISPATCH_H
#define DOUBLE_DISPATCH_H

#include <map>
#include <functional>

namespace Engine
{
	template <typename KEY, typename TYPE>
	class DoubleDispatch
	{
		private:
			std::map <std::pair <KEY, KEY>, std::function <void (TYPE*, TYPE*)>> m_handlerMap;

		public:
			bool RegisterHandlerFunction(const std::pair <KEY, KEY>& keyPair, std::function <void (TYPE*, TYPE*)> func)
			{
				auto it = m_handlerMap.find(keyPair);
				if(it != m_handlerMap.end()) return false;

				m_handlerMap[keyPair] = func;
				return true;
			}

			bool Handle(TYPE* a, const KEY& ak, TYPE* b, const KEY& bk)
			{
				std::pair <KEY, KEY> pair(ak, bk);
				
				auto it = m_handlerMap.find(pair);
				if(it == m_handlerMap.end())
				{
					std::swap(pair.first, pair.second);
					it = m_handlerMap.find(pair);
					if(it == m_handlerMap.end()) return false;
				}
				it ->second(a, b);
				return true;
			}
	};
}

#endif
